/*
** commands.c
**
** Ed, Version 1.51, Copyright (c) 1992-94 SoftCircuits
** Redistributed by permission.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <io.h>
#include <pictor.h>
#include "ed.h"

#ifdef EXT_ED
	#include <dos.h>
	/* ANSI/ISO C names, Watcom header */
	#ifdef __WATCOMC__
		#include <direct.h>
		#define dos_getfileattr _dos_getfileattr
		#define chdir _chdir
	#else
		#include <dir.h>
	#endif
#endif


static int save_result = FALSE;

#define MAX_BUFF	65
static char findbuff[MAX_BUFF + 1];
static char replacebuff[MAX_BUFF + 1];


/*
** displays Using-Help help topic
*/
void using_help()
{
	helprun(hlp_usinghlp);

} /* using_help */

/*
** activates help index
*/
void help_index()
{
	helprun(NULL);

} /* help_index */

/*
** display program version and copyright info
*/
void about()
{
	helpsetcontext(hlp_about);
	messagebox(copyright,"About",MB_OK,&msgcolors);

} /* about */

/*
** set tab stop width
*/
void set_tabwidth()
{
	int done = FALSE,new_width;
	char buffer[15];

	helpsetcontext(hlp_tabwidth);
	pushstatus();

	itoa(tab_size,buffer,10);
	statusbar("Enter tab between 2 and 20");

	while(!done) {
		if(editbox("Enter new tab width",buffer,3,NULL,&msgcolors)) {
			new_width = atoi(buffer);
			if(new_width >= 2 && new_width <= 20) {
				tab_size = new_width;
				update_state = UPDATE_REPAINT;
				update_cursor(FALSE);
				done = TRUE;
			}
			else {
				messagebox("You must enter a number between 2 and 20",NULL,
					MB_OK,&msgcolors);
			}
		}
		else done = TRUE;
	}
	popstatus();

} /* set_tabwidth */

/*
** attempts to save the current file if:
** 	it has been modified
** 	the user wants to save it
**
** returns FALSE if attempt to save fails or if the current file
** is modified and the user selects cancel from the message box
*/
int save_modified()
{
	int result = TRUE;

	if(modified) {
		result = messagebox("Current file has changed\n"
			"Do you want to save it?",	NULL,MB_YESNOCANCEL,&msgcolors);
		if(result == 2) {
			filesave();
			result = save_result;
		}
	}
	return(result);

} /* prompt_save */

/*
** create a new file
*/
void filenew()
{
	helpsetcontext(hlp_new);

	if(save_modified())
		new_file(NULL);

} /* filenew */

/*
** load a new file from disk
*/
void fileopen()
{
	char *ptr;
	
	#ifdef EXT_ED
		/* int traversing_dirs; */
		unsigned int file_attr;
	#endif

	helpsetcontext(hlp_open);
	
	#if defined(EXT_ED) && defined(EXT_PICKFILE)
		if(save_modified()) {
			while(TRUE)
			{
				ptr = pickfile("*.*","Open File",&msgcolors);
				dos_getfileattr(ptr, &file_attr);
				if(!(file_attr & _A_SUBDIR))
				{
					load_file(ptr);
					break;
				}
				else if(ptr != NULL)
				{
					chdir(ptr);
				}
				else
				{
					break;
				}
			}
		}

	#else
		if(save_modified()) {
			ptr = pickfile("*.*","Open File",&msgcolors);
			if(ptr != NULL)
				load_file(ptr);
		}
	#endif

} /* fileopen */

/*
** save the current file
*/
void filesave()
{
	helpsetcontext(hlp_save);

	if(!stricmp(filename,untitled))
		filesaveas();
	else
		save_result = save_file(filename);

} /* filesave */

/*
** save the curretn file with a different name
*/
void filesaveas()
{
	char buffer[65 + 1];

	helpsetcontext(hlp_saveas);

	save_result = FALSE;
	*buffer = '\0';

	while(editbox("Save current file as",buffer,65,NULL,&msgcolors)
		&& *buffer) {
		strupr(buffer);
		if(!access(buffer,0x00)) {
			if(!messagebox("File already exists\nDo you want to overwrite it?",
				buffer,MB_YESNO,&msgcolors)) {
				*buffer = '\0';
				continue;
			}
		}
		save_result = save_file(buffer);
		break;
	}

} /* filesaveas */

/*
** called from file print to send current file to printer
*/
static int do_print()
{
	int i,j,col,tab_cols;
	LINE *line;

	for(line = head;line != NULL;line = line->next) {
		for(col = 0,i = 0;i < line->len;i++) {
			if(line->text[i] == '\t') {
				tab_cols = (tab_size - (col % tab_size));
				for(j = 0;j < tab_cols;j++) {
					if(prnputc(' '))
						return(FALSE);
				}
				col += tab_cols;
			}
			else {
				if(prnputc(line->text[i]))
					return(FALSE);
				col++;
			}
		}
		if(prnputs("\r\n"))
			return(FALSE);
	}
	/* send form feed */
	if(prnputc('\x0C'))
		return(FALSE);

	return(TRUE);

} /* do_print */

/*
** sends the current file to the printer
*/
void fileprint()
{
	helpsetcontext(hlp_print);
	if(!messagebox("Send file to printer?","Print",MB_YESNO,&msgcolors))
		return;

	pushstatus();
	xprintf(statusbar,"Printing %s",filename);

	if(!do_print()) {
		messagebox("Error printing file","Error",MB_OK,&msgcolors);
		clearerr(stdprn);
	}
	popstatus();

} /* fileprint */

/*
** searches the current file starting at the current location
** for the text in findbuff
** if the text is found, the file positon is move to the find location
** if the text is not found and msg == TRUE, a message is displayed
*/
static int find_text(int msg,int start_col)
{
	LINE *line;
	int i,row;

	pushstatus();
	statusbar("Searching...");

	row = file_row;
	i = start_col;
	for(line = curr_line;line != NULL;line = line->next,row++) {
		for( ;i < line->len;i++) {
			if(toupper(line->text[i]) == toupper(*findbuff)) {
				if(!strnicmp(line->text + i,findbuff,strlen(findbuff))) {
					curr_line = line;
					file_row = row;
					line_ndx = i;
					if(row < top_row || row >= top_row + EDIT_ROWS) {
						if(row > 5) {
							top_row = row - 5;
							for(i = 0;i < 5;i++)
								line = line->prev;
							top_line = line;
						}
						else {
							top_row = 0;
							top_line = head;
						}
					}
					popstatus();
					update_state = UPDATE_REPAINT;
					update_cursor(TRUE);
					return(TRUE);
				}
			}
		}
		i = 0;
	}
	popstatus();
	if(msg) {
		sprintf(buffer,"Text not found:\n\"%s\"",findbuff);
		messagebox(buffer,NULL,MB_OK,&msgcolors);
	}

	return(FALSE);

} /* find_text */

/*
** searches for the specified text
*/
void search()
{
	helpsetcontext(hlp_find);

	if(editbox("Find",findbuff,MAX_BUFF,NULL,&msgcolors) && *findbuff)
		find_text(TRUE,line_ndx + 1);

} /* search */

/*
** locates and changes the specified text
*/
void change()
{
	static MEDITSTRUCT medit[] = {
		{ "Find",			findbuff,	MAX_BUFF },
		{ "Replace with", replacebuff,MAX_BUFF },
	};
	char buffer[31];
	int key,len1,len2,count = 0,changeall = FALSE;
	int skip = FALSE,first_time = TRUE;

	helpsetcontext(hlp_change);

	if(multiedit(medit,2,"Change",&msgcolors)) {
		len1 = strlen(findbuff);
		len2 = strlen(replacebuff);
		if(len1 == 0)
			return;
		if(len2 == 0) {
			if(!messagebox("Blank replacement string\nText will be deleted",
				"Warning",MB_OKCANCEL,&msgcolors))
				return;
		}
		while(find_text(first_time,line_ndx + skip)) {
			first_time = FALSE;
			skip = FALSE;
			if(!changeall) {
				statusbar("Replace this occurance [Y/N]?  <A>=Replace all "
					" <Escape>=Done  <F1>=Help");

				while(TRUE) {
					key = kbdread();
					if(key == ESCAPE_KEY)
						break;
					else if(key == F1_KEY) {
						helprun(hlp_change);
						continue;
					}
					key = toupper(key & 0xFF);
					if(key == 'A') {
						changeall = TRUE;
						break;
					}
					else if(key == 'Y')
						break;
					else if(key == 'N') {
						skip = TRUE;
						break;
					}
					else beep();
				}
				if(key == ESCAPE_KEY)	/* escape */
					break;
				if(skip) 				/* skip this one */
					continue;
			}
			else if(kbdready()) {
				if(kbdread() == ESCAPE_KEY)
					break;
				else
					beep();
			}
			if(len1 > len2)
				shrink_line(&curr_line,line_ndx,len1 - len2);
			else if(len1 < len2)
				if(!expand_line(&curr_line,line_ndx,len2 - len1))
					break;
			memmove(curr_line->text + line_ndx,replacebuff,len2);
			show_line(curr_line,(file_row - top_row) + edit_top);

			/* don't search replaced text */
			line_ndx += len2;
			update_cursor(TRUE);

			modified = TRUE;
			count++;
		}
		show_status();
		if(!first_time) {
			sprintf(buffer,"%d change(s) made",count);
			messagebox(buffer,NULL,MB_OK,&msgcolors);
		}
	}

} /* change */

/*
** repeats the last search
*/
void repeatsearch()
{
	if(*findbuff != '\0') {
		helpsetcontext(hlp_repeatfind);
		find_text(TRUE,line_ndx + 1);
	}
	else search();

} /* repeatsearch */


/* Additional (new) commands go here. Changes to already-existing
 * commands go in their respective functions.- W. Jones */

#ifdef EXT_ED
void cut()
{
}

void copy()
{
}

void paste()
{
}

void del()
{
}

void undo()
{
}

void redo()
{
}

void gotoDOS()
{
	pushcurs();
	pushstatus(); 
	removeclock();
	
	vcolor(foreback(WHITE,BLACK));
	cls();
	system("COMMAND.COM");
	vcolor(edit_color); 
	cls();
	
	popcurs();
	popstatus();
	installclock(1,vcfg.columns - 7,mnucolors.normal);
	show_text();
}
#endif
